package com.atguigu.crowd.mvc.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.util.matcher.AndRequestMatcher;

import com.atguigu.crowd.constant.CrowdConstant;

// 注意！这个类一定要放在自动扫描的包下，否则所有配置都不会生效！

// 将当前类标记为配置类
@Configuration
// 启用Web环境下权限控制功能
@EnableWebSecurity
//要使方法上的分配权限的注解生效需要配置该注解
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Autowired
	private CrowdUserDetailsService userDetailsService;
	
	@Autowired
	private BCryptPasswordEncoder passwordEncoder;
	
	/*
	 * adminServiceImpl中的save方法中的密码
	 * 父类IOC容器无法用子类IOC容器的bean对象，需在父类IOC容器配置
	 * @Bean
	public BCryptPasswordEncoder getBCryptPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}*/
	
	//数据库操作登录页面的用户名和密码
	@Override
	protected void configure(AuthenticationManagerBuilder builder) throws Exception {
		builder
		.userDetailsService(userDetailsService)
		.passwordEncoder(passwordEncoder) 
		;

	}
	
	//设置授权
	@Override
	protected void configure(HttpSecurity security) throws Exception {
		
		security
		.authorizeRequests()//对请求进行授权
		.antMatchers(
				"/admin/to/login/page.html",
				"/bootstrap/**",
				"/crowd/**",
				"/css/**",
				"/font/**",
				"/img/**",
				"/jquery/**"
				).permitAll()//设置无条件访问的地址
		/*.antMatchers("/admin/get/page.html")//用户经理具有访问用户列表的权限
		.hasRole("用户经理")*/
		.anyRequest()//其他请求
		.authenticated()//需要认证
		.and()
		.csrf()
		.disable()//禁用csrf
		.formLogin()//登录表单
		.loginPage("/admin/to/login/page.html")//登录页面地址
		.loginProcessingUrl("/security/do/login.html")//登录处理的地址
		.defaultSuccessUrl("/admin/to/main/page.html")//登录成功去的地址
		.usernameParameter("loginAcct")//设置用户名参数
		.passwordParameter("userPswd")//设置密码参数
		.and()
		.logout()//退出登录
		.logoutUrl("/seucrity/do/logout.html")//退出登录的地址
		.logoutSuccessUrl("/admin/to/login/page.html")//退出登录成功去的地址
		.and()
		.exceptionHandling()//配置异常访问禁止的处理类
		.accessDeniedHandler(new AccessDeniedHandler() {
			
			@Override
			public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exception)
					throws IOException, ServletException {
				request.setAttribute("exception", new Exception(CrowdConstant.MESSAGE_ACCESS_DENIED));
				request.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(request, response);
			}
		})
		;
	}
}
